/*
 * Copyright (c) 2020 hebeiyiliuba.com
 * All rights reserved.
 *
 */
package org.jeecg.modules.wlhy.report.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.enums.ReportPlatformEnum;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.third.amap.dto.MapDirectionDTO;
import org.jeecg.modules.third.amap.service.AmapService;
import org.jeecg.modules.third.jg.jss.report.cfccapitalflow.service.CfcCapitalflowService;
import org.jeecg.modules.third.jg.jss.report.cfcdriverinfo.service.CfcDriverinfoService;
import org.jeecg.modules.third.jg.jss.report.cfcshipperinfo.service.CfcShipperinfoService;
import org.jeecg.modules.third.jg.jss.report.cfcshippingnoteinfo.service.CfcShippingnoteinfoService;
import org.jeecg.modules.third.jg.jss.report.cfcsourcegoodsinfo.service.CfcSourcegoodsinfoService;
import org.jeecg.modules.third.jg.jss.report.cfcvehicleinfo.service.CfcVehicleinfoService;
import org.jeecg.modules.third.jg.report.freight.information.dto.AppInfoDTO;
import org.jeecg.modules.third.openapi.WaybillRouteService;
import org.jeecg.modules.wlhy.bill.entity.HyShippingNoteBill;
import org.jeecg.modules.wlhy.bill.service.IHyShippingNoteBillService;
import org.jeecg.modules.wlhy.company.entity.HyCompany;
import org.jeecg.modules.wlhy.company.service.IHyCompanyService;
import org.jeecg.modules.wlhy.customer.entity.HyCustomerAddressReceive;
import org.jeecg.modules.wlhy.customer.entity.HyCustomerAddressSend;
import org.jeecg.modules.wlhy.customer.entity.HyCustomerCompany;
import org.jeecg.modules.wlhy.customer.service.IHyCustomerAddressReceiveService;
import org.jeecg.modules.wlhy.customer.service.IHyCustomerAddressSendService;
import org.jeecg.modules.wlhy.customer.service.IHyCustomerCompanyService;
import org.jeecg.modules.wlhy.customer.service.impl.HyCustomerServiceImpl;
import org.jeecg.modules.wlhy.hyconfig.entity.HyConfig;
import org.jeecg.modules.wlhy.hydriver.entity.HyDriver;
import org.jeecg.modules.wlhy.hydriver.entity.HyDriverReport;
import org.jeecg.modules.wlhy.hydriver.service.IHyDriverReportService;
import org.jeecg.modules.wlhy.hydriver.service.IHyDriverService;
import org.jeecg.modules.wlhy.hyinsurance.entity.InsuranceApplyRecord;
import org.jeecg.modules.wlhy.hyinsurance.service.InsuranceApplyRecordService;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicle;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicleReport;
import org.jeecg.modules.wlhy.hyvehicle.entity.HyVehicleType;
import org.jeecg.modules.wlhy.hyvehicle.service.IHyVehicleReportService;
import org.jeecg.modules.wlhy.hyvehicle.service.IHyVehicleService;
import org.jeecg.modules.wlhy.order.entity.HyOrder;
import org.jeecg.modules.wlhy.order.entity.HyOrderDTO;
import org.jeecg.modules.wlhy.order.service.IHyOrderService;
import org.jeecg.modules.wlhy.report.IReportService;
import org.jeecg.modules.wlhy.shipping.constant.ShippingPayStatus;
import org.jeecg.modules.wlhy.shipping.entity.HyShippingNote;
import org.jeecg.modules.wlhy.shipping.entity.WaybillRouteVO;
import org.jeecg.modules.wlhy.shipping.service.IHyShippingNoteService;
import org.jeecg.modules.wlhy.utils.HyCfgUtil;
import org.jeecg.modules.wlhy.utils.HyConfigUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * @BelongsPackage: org.jeecg.modules.wlhy.report.impl
 * @Author: duanlikao
 * @CreateTime: 2023-03-09 09:48
 * @Description:
 * @Version: 1.0
 */
@Service
@Slf4j
public class JsuReportService implements IReportService {

    @Resource
    private BaseReportService baseReportService;

    @Resource
    private IHyDriverService driverService;

    @Resource
    private IHyVehicleService vehicleService;

    @Autowired
    private IHyCustomerCompanyService customerCompanyService;

    @Autowired
    private IHyShippingNoteService hyShippingNoteService;

    @Autowired
    private IHyShippingNoteBillService hyShippingNoteBillService;

    @Autowired
    private HyCustomerServiceImpl customerService;

    @Resource
    private IHyCustomerAddressSendService customerAddressSendService;

    @Resource
    private IHyCustomerAddressReceiveService customerAddressReceiveService;

    /**
     * 申报企业信息
     */
    @Autowired
    private IHyCompanyService companyService;


    @Resource
    private IHyDriverReportService hyDriverReportService;


    @Resource
    private IHyVehicleReportService vehicleReportService;

    @Autowired
    private IHyOrderService orderService;

    @Autowired
    private InsuranceApplyRecordService insuranceApplyRecordService;

    @Autowired
    private AmapService amapService;

    /**
     * 江苏省司机信息
     */
    @Resource
    private CfcDriverinfoService driverinfoService;

    /**
     * 江苏省车辆信息
     */
    @Resource
    private CfcVehicleinfoService vehicleinfoService;

    /**
     * 江苏省托运人/货主信息
     */
    @Resource
    private CfcShipperinfoService shipperinfoService;

    /**
     * 江苏省货源信息信息
     */
    @Resource
    private CfcSourcegoodsinfoService sourcegoodsinfoService;
    /**
     * 江苏省运单信息
     */
    @Resource
    private CfcShippingnoteinfoService shippingnoteinfoService;

    /**
     * 江苏省资金流水信息
     */
    @Resource
    private CfcCapitalflowService capitalflowService;

    @Autowired
    private WaybillRouteService waybillRouteService;

    @Value(value="${js-report-platform.enterpriseCode:}")
    private String enterpriseCode;

    @Override
    public ReportPlatformEnum getReportType() {
        return ReportPlatformEnum.REPORT_PLATFORM_JS;
    }

    @Override
    public void checkReport() {
        //江苏监管平台
        if(!HyCfgUtil.isUsed2("jiangsu_report")){
            throw new JeecgBootException("江苏监管平台未配置参数!");
        }

        if (StrUtil.isEmpty(this.enterpriseCode)) {
            throw new JeecgBootException("江苏监管参数配置错误，请联系管理员。");
        }
    }

    @Override
    public AppInfoDTO getAppInfo() {
        return null;
    }


    @Override
    @Deprecated
    public boolean report(HyShippingNote hyShippingNote) {
        return false;
    }


    @Override
    public Result reportShippingNote(HyShippingNote hyShippingNote) {
        Result result = this.baseReportService.checkDriverAndVehicle(hyShippingNote.getId());
        if (!result.getCode().equals(CommonConstant.SC_OK_200)) {
            return result;
        }

        return this.uploadShippingNote(hyShippingNote);
    }

    @Override
    public Result reportCapitalFlow(HyShippingNote hyShippingNote) {
        Result result = this.baseReportService.checkDriverAndVehicle(hyShippingNote.getId());
        if (!result.getCode().equals(CommonConstant.SC_OK_200)) {
            return result;
        }

        return this.uploadCapitalFlow(hyShippingNote);
    }


    public Result uploadShippingNote(HyShippingNote hyShippingNote) {
        QueryWrapper<HyCustomerCompany> queryWrapperCustomerCompany = new QueryWrapper();
        queryWrapperCustomerCompany.eq("customer_id", hyShippingNote.getCustomerId());
        //查询货主签约
        HyCustomerCompany customerCompany = customerCompanyService.getOne(queryWrapperCustomerCompany);

        HyOrder hyOrder = orderService.getById(hyShippingNote.getOrderId());

        HyDriver hyDriver = driverService.getById(hyShippingNote.getDriverId());

        HyVehicle hyVehicle = vehicleService.getById(hyShippingNote.getVehicleId());

        HyCompany company = companyService.getById(hyShippingNote.getCompanyId());

        if (StrUtil.isEmpty(customerCompany.getContractNumber())) {
            throw new JeecgBootException("货主签约合同编号不能为空");
        }

        //先用高德模拟轨迹查公里数
        if (StrUtil.isEmpty(hyShippingNote.getTransportationDistance())) {
            MapDirectionDTO mapDirectionDTO = this.amapService.getMapGpsOrder(hyOrder);
            if (ObjectUtil.isNotEmpty(mapDirectionDTO)) {
                log.info("江苏上报模拟轨迹公里数， {}", mapDirectionDTO.getDistance());
                hyShippingNote.setTransportationDistance(mapDirectionDTO.getDistance());
            }
        }

        //如果模拟运输距离为空，使用中交接口查询轨迹公里数
        if (StrUtil.isEmpty(hyShippingNote.getTransportationDistance())) {
            //运单车辆轨迹查询
            String startTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtReceive());
            String endTime = DateUtils.dateTimeToString(hyShippingNote.getStatusDtUnloading());
            String vehicleColor = StringUtils.isNotEmpty(hyVehicle.getVehiclePlateColorCode()) ? hyVehicle.getVehiclePlateColorCode() : "2";
            WaybillRouteVO waybillRouteVO = this.waybillRouteService.getWaybillRoute(hyVehicle.getVehicleNumber(), vehicleColor, startTime, endTime, "GCJ02");
            if (null == waybillRouteVO || org.springframework.util.CollectionUtils.isEmpty(waybillRouteVO.getPointDataList())) {
                throw new JeecgBootException("江苏上报失败: 该运单没有车辆轨迹！");
            }

            if (StrUtil.isEmpty(waybillRouteVO.getMileage())) {
                throw new JeecgBootException("江苏上报失败: 该运单运输公里数为0");
            }

            hyShippingNote.setTransportationDistance(waybillRouteVO.getMileage());
        }

        HyOrderDTO hyOrderDTO = new HyOrderDTO();
        BeanUtil.copyProperties(hyOrder, hyOrderDTO, true);
        if (StrUtil.isNotEmpty(hyShippingNote.getInsuranceNo())) {
            //赋值保险单据信息
            InsuranceApplyRecord insuranceApplyRecord = this.insuranceApplyRecordService.getById(hyShippingNote.getInsuranceNo());
            hyOrderDTO.setInsuranceCompany(insuranceApplyRecord.getInsuranceCompany());
            hyOrderDTO.setInsuranceCompanyNumber(insuranceApplyRecord.getInsuranceCompanyNumber());
            hyOrderDTO.setInsurancePolicy(insuranceApplyRecord.getInsurancePolicy());
            hyOrderDTO.setInsuranceUrl(insuranceApplyRecord.getPdfUrl());
        }
        log.warn("江苏监管运单数据上报，{}", JSONUtil.toJsonStr(hyShippingNote));

        if (!"1".equals(hyShippingNote.getUploadStatus())) {
//            HyCustomerAddressSend hyCustomerAddressSend = this.customerAddressSendService.getById(hyShippingNote.getAddressSendId());
//            HyCustomerAddressReceive hyCustomerAddressReceive = this.customerAddressReceiveService.getById(hyShippingNote.getAddressReceiveId());
//            if (null == hyCustomerAddressSend || null == hyCustomerAddressReceive) {
//                throw new JeecgBootException("收发货地址地图坐标选取不能为空");
//            }
//            hyShippingNote.setSendLatitude(hyCustomerAddressSend.getLatitude());
//            hyShippingNote.setSendLongitude(hyCustomerAddressSend.getLongitude());
//            hyShippingNote.setReceiveLatitude(hyCustomerAddressReceive.getLatitude());
//            hyShippingNote.setReceiveLongitude(hyCustomerAddressReceive.getLongitude());

            //货主
            shipperinfoService.setEnterpriseCode(this.enterpriseCode);
            shipperinfoService.addShipperinfo(
                    customerService.getById(hyShippingNote.getCustomerId())
            );
            BigDecimal costPayShipping = hyShippingNote.getDriverFee() ;

            //货源
            sourcegoodsinfoService.setEnterpriseCode(this.enterpriseCode);
            sourcegoodsinfoService.insertSourcegoodsinfo(hyOrderDTO, customerCompany, company, costPayShipping);
            //运单
            shippingnoteinfoService.setEnterpriseCode(this.enterpriseCode);
            boolean resShippingNote = shippingnoteinfoService.inserShippingNoteInfo(hyShippingNote, company, hyOrder, hyDriver, hyVehicle);
            if (resShippingNote) {
                hyShippingNote.setUploadDate(new Date());
                hyShippingNote.setUploadStatus("1");
                hyShippingNote.setReportPlatformType(ReportPlatformEnum.REPORT_PLATFORM_JS.getCode());
                hyShippingNoteService.updateById(hyShippingNote);

                return Result.OK("上报成功");
            }

            return Result.error("上报失败");
        }

        return Result.OK("成功");
    }


    public Result uploadCapitalFlow(HyShippingNote hyShippingNote) {
        QueryWrapper<HyCustomerCompany> queryWrapperCustomerCompany = new QueryWrapper();
        queryWrapperCustomerCompany.eq("customer_id", hyShippingNote.getCustomerId());

        HyShippingNote shippingNote = hyShippingNoteService.getById(hyShippingNote.getId());
        if (!shippingNote.getUploadStatus().equals("1")) {
            return Result.error("请先上报运单数据");
        }

        if (!shippingNote.getShippingPayStatus().equals(ShippingPayStatus.支付完成.getValue())) {
            return Result.error("该运单未支付完成");
        }

        log.warn("江苏监管运单数据上报，{}", JSONUtil.toJsonStr(hyShippingNote));

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("shipping_id", hyShippingNote.getId());
        queryWrapper.ne("upload_status", "1");
        List<HyShippingNoteBill> shippingNoteBills = hyShippingNoteBillService.list(queryWrapper);
        if(CollectionUtils.isNotEmpty(shippingNoteBills)){
            capitalflowService.setEnterPriseCode(this.enterpriseCode);
            if (capitalflowService.inserCapitalflow(shippingNoteBills, hyShippingNote)) {
                for(HyShippingNoteBill shippingNoteBill:shippingNoteBills){
                    shippingNoteBill.setUploadDate(new Date());
                    shippingNoteBill.setUploadStatus("1");
                    shippingNoteBill.setReportPlatformType(ReportPlatformEnum.REPORT_PLATFORM_JS.getCode());
                }

                hyShippingNoteBillService.updateBatchById(shippingNoteBills);
                return Result.OK("上报成功");
            }
        }

        return Result.error("上报资金流水数据错误");
    }

    /**
     * 按运单上传司机和车辆信息
     * @param vehicleId
     */
    public Result uploadVehicle(String vehicleId) {

        HyVehicle hyVehicle = vehicleService.getById(vehicleId);
        if (null == hyVehicle) {
            return Result.error("未找到车辆数据");
        }

        String driverId = hyVehicle.getDriverId();
        if (StrUtil.isEmpty(driverId)) {
            return Result.error("上报错误: 车辆未绑定司机");
        }

        log.warn("江苏监管车辆数据上报，{}", JSONUtil.toJsonStr(hyVehicle));

        HyVehicleReport hyVehicleReport = new HyVehicleReport();
        if(!vehicleService.checkRTCNoV2(hyVehicle)){
            hyVehicleReport.setId(vehicleId);
            hyVehicleReport.setVehicleId(vehicleId);
            hyVehicleReport.setReportPlatformType(ReportPlatformEnum.REPORT_PLATFORM_JS.getCode());
            hyVehicleReport.setVehicleUploadStatus( "2");
            hyVehicleReport.setUploadDate( new Date() );
            hyVehicleReport.setVehicleReportFailureReason("车辆道路运输证号不正确或者已过期，请修改后重新上传！");
            vehicleReportService.saveVehicleReport(hyVehicleReport);

            throw new JeecgBootException("车辆道路运输证号不正确或者已过期，请修改后重新上传！");
        }else {
            hyVehicle.setCarrierId(driverId);
            HyVehicleType vehicleType = vehicleService.getHyVehicleType(hyVehicle.getVehicleType());
            hyVehicle.setVehicleType(
                    vehicleType != null ? vehicleType.getValue() : "Q11"
            );
            vehicleinfoService.setEnterpriseCode(this.enterpriseCode);
            boolean dvUploadStatus = vehicleinfoService.addVehicleinfo(hyVehicle);
            if (dvUploadStatus) {
                hyVehicleReport.setId(vehicleId);
                hyVehicleReport.setVehicleId(vehicleId);
                hyVehicleReport.setReportPlatformType(ReportPlatformEnum.REPORT_PLATFORM_JS.getCode());
                hyVehicleReport.setVehicleUploadStatus( "1");
                hyVehicleReport.setUploadDate( new Date() );
                hyVehicleReport.setVehicleReportFailureReason("");
                vehicleReportService.saveVehicleReport(hyVehicleReport);
                this.vehicleService.updateJsUploadStatusById(vehicleId, "1");
            } else {
                this.vehicleService.updateJsUploadStatusById(vehicleId, "2");
            }

            return dvUploadStatus ? Result.OK("同步车辆数据成功") : Result.error("同步车辆数据错误");
        }
    }


    public Result uploadDriver(String driverId) {
        HyDriver hyDriver = driverService.getById(driverId);
        if(null == hyDriver) {
            return Result.error("未找到司机数据");
        }

        List<HyVehicle> hyVehicleList = vehicleService.getVehicleByDriverId(driverId);
        //HyVehicle hyVehicle = vehicleService.getById(vehicleId);
        if (CollUtil.isEmpty(hyVehicleList)) {
            return Result.error("未找到司机对应的车辆数据");
        }
        //取一辆车
        HyVehicle hyVehicle = hyVehicleList.get(0);

        log.warn("江苏监管司机数据上报，{} {}", JSONUtil.toJsonStr(hyDriver), JSONUtil.toJsonStr(hyVehicle));

        HyDriverReport hyDriverReport = new HyDriverReport();
        //人员从业资格证验证
        if(!driverService.checkQualificationV2(hyDriver)){
            hyDriverReport.setId(driverId);
            hyDriverReport.setDriverId(driverId);
            hyDriverReport.setReportPlatformType(ReportPlatformEnum.REPORT_PLATFORM_JS.getCode());
            hyDriverReport.setDriverUploadStatus( "2");
            hyDriverReport.setUploadDate( new Date() );
            hyDriverReport.setDriverReportFailureReason( "人员从业资格证验证号不正确或者已过期，请修改后重新上传！");
            hyDriverReportService.saveDriverReport(hyDriverReport);
            throw new JeecgBootException("人员从业资格证验证号不正确或者已过期，请修改后重新上传！");
        } else {
            driverinfoService.setEnterpriseCode(this.enterpriseCode);
            boolean dvUploadStatus = driverinfoService.addDriverinfo(hyDriver, hyVehicle);
            if (dvUploadStatus) {
                hyDriverReport.setId(driverId);
                hyDriverReport.setDriverId(driverId);
                hyDriverReport.setReportPlatformType(ReportPlatformEnum.REPORT_PLATFORM_JS.getCode());
                hyDriverReport.setDriverUploadStatus( "1");
                hyDriverReport.setUploadDate( new Date() );
                hyDriverReport.setDriverReportFailureReason( "");
                hyDriverReportService.saveDriverReport(hyDriverReport);
                this.driverService.updateJsUploadStatusById(driverId, "1");
            } else {
                this.driverService.updateJsUploadStatusById(driverId, "2");
            }

            return dvUploadStatus ? Result.OK("同步司机数据成功") : Result.error("同步司机数据错误");
        }
    }
}
